package com.elite.groovy.callback

import com.elite.groovy.kh.KHDBConfig
import com.elite.groovy.kh.KHUtil
import com.elite.groovy.kh.LogToDB
import com.elite.groovy.util.EliteBean
import com.elite.groovy.util.Util
import net.sf.json.JSONObject
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.text.SimpleDateFormat

/**
 * @projectName: Groovy*
 * @package: com.elite.groovy.callback*
 * @className: apiAutoSendMessage*
 * @description: 查询待发送短信表，定时发送企业微信消息及短信，
 * @author: demi*
 * @date: 2023-09-01
 * @version: 1.0
 */

class apiAutoSendMessage implements ServiceBackInvoke {
    private static final Logger log = LoggerFactory.getLogger(apiAutoSendMessage.class)
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    private static String DGQW_KEY = "";
    private static String DGQW_AGENTID = "";
    private static String DGQW_SENDMSM = "";
    private static String QW_AgentID = ""; // 原生企微发送时

    private static String SMS_CallbackURL = "";

    private static String SYS_OuterDomain = "";


    String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8")
        response.setContentType("application/json;charset=UTF-8")
        long startTime = System.currentTimeMillis()

        //设置返回参数
        JSONObject resultJson = new JSONObject()
        resultJson.put("errcode", 0)
        resultJson.put("errmsg", "")
        resultJson.put("msgid", "")

        //获取调用方式
        String getMethod = request.getMethod()
        log.debug("getMethod:" + getMethod)
        //接收客户端调用参数
        String callInfo = ""
        InputStreamReader reader = new InputStreamReader(request.getInputStream(), "UTF-8")
        BufferedReader iny = new BufferedReader(reader)
        String line
        while ((line = iny.readLine()) != null) {
            callInfo += line
        }
        log.info("[调用请求信息]:" + callInfo)

        // 企微发送类型
        String QW_SendType = KHDBConfig.getParamConfig(eliteBean, "QW_SendType"); // 1 原生 其他德高转发接口

        //短信发送流程
        try {
            //查找待发送任务
            String sql1 = '''Select t.Documentout_Guid,
                                   t.Doctype,
                                   Documentfrom,
                                   t.Documentto,
                                   t.Documentpath,
                                   t.Documentpath2,
                                   Uuid() As Uid,
                                   Dl.Description As Title,
                                   t.Send_Url,
                                   case when cs.parameter_value is null then '58778defa73e383a742e24c153b84096' else cs.parameter_value  end as parameter_value,
                                   t.Objective_Guid
                              From Documentout t
                              Left Join Doctemplate Dl
                                On t.Template_Id = Dl.Doctemplate_Id
                              left join sys_parameter_config cs on Dl.apikey=cs.Parameter_ID
                             Where 1 = 1
                               And t.Doctype In (3, 8)
                               And t.Status = '0'
                               And t.Trialcount < t.Trialcountlimit
                               And Ifnull(t.Expectedstartdate, Now()) <= Now()
                             Order By t.Expectedstartdate Limit 200''';
            List getSmsSelectSQL = eliteBean.chaxun_sql(sql1, "dataSource")
            log.debug("SQL获取待发送数据量:" + getSmsSelectSQL.size())
            if (getSmsSelectSQL.size() > 0) {

                // 短信发送结果回调地址
                SMS_CallbackURL = KHUtil.isNull(SMS_CallbackURL) ? KHDBConfig.getAPIURL(eliteBean, "SYS-SMS_CallbackURL") : SMS_CallbackURL;

                for (int i = 0; i < getSmsSelectSQL.size(); i++) {
                    Map selectResultcm = getSmsSelectSQL.get(i)
                    String DOCUMENTOUT_GUID = selectResultcm.get("Documentout_Guid") // 短信主键
                    String DOCTYPE = selectResultcm.get("Doctype") // 短信类型
                    String DOCUMENTFROM = selectResultcm.get("Documentfrom") // 企业微信：填0表示发送至西卡BFM企微，填1表示发送至西卡德高企微
                    String DOCUMENTTO = selectResultcm.get("Documentto") // 号码
                    String DOCUMENTPATH = selectResultcm.get("Documentpath") // 短信内容
                    String documentpath2 = selectResultcm.get("Documentpath2") // 模板消息的话发送的报文Data-Davco
                    String uid = selectResultcm.get("Uid") // 随机数 后续回写接口使用
                    String title = selectResultcm.get("Title") // 模板描述|标题
                    String send_url = selectResultcm.get("Send_Url") // 发送URL
                    String parameter_value = selectResultcm.get("parameter_value") // parameter_value
                    String Objective_Guid = selectResultcm.get("Objective_Guid") // Objective_Guid
                    log.debug("待发送DOCTYPE：" + DOCTYPE);
                    if (DOCTYPE == "8") {

                        if (QW_SendType == "1") {
                            //调用原生企业微信发送消息
                            sendQwMessage(eliteBean, title, send_url, DOCUMENTOUT_GUID, DOCUMENTTO, documentpath2);
                        } else {
                            // 调用德高中间件接口发送企业微信消息
                            sendWmsMessage(eliteBean, title, send_url, DOCUMENTOUT_GUID, DOCUMENTTO, documentpath2, DOCUMENTFROM.toInteger())
                        }

                    } else if (DOCTYPE == "3") {
                        //短信
                        sendSmsMessage(eliteBean, DOCUMENTOUT_GUID, DOCUMENTTO, DOCUMENTPATH, uid,parameter_value,Objective_Guid)
                    }
                }
            }
        } catch (Exception e) {
            log.error("接口处理异常", e)
            resultJson.put("errcode", -1)
            resultJson.put("errmsg", "接口处理异常" + e.getMessage())
        } finally {
            LogToDB.toDB(eliteBean, "dataSource", "发送企微消息[德高接口]", "apiAutoSendMessage", "", resultJson.toString(), "本次发送总耗时：" + (System.currentTimeMillis() - startTime).toString(), getMethod)
        }
        return "success"
    }

    // 发送-短信（调用云片接口）
    static String sendSmsMessage(EliteBean eliteBean, String DOCUMENTOUT_GUID, String DOCUMENTTO, String DOCUMENTPATH, String uid,String parameter_value,String Objective_Guid) {
        JSONObject resultJson = new JSONObject()
        long startTime = System.currentTimeMillis()
        String code = "-1" //短信发送状态
        String msg = "" //短信发送失败原因
        try {
            Map<String, String> paramHashMap = new HashMap<String, String>()
            //paramHashMap.put("apikey", KHDBConfig.getParamConfig(eliteBean, "YUNPIAN_TZ_apiKey"))
            paramHashMap.put("apikey", parameter_value)
            paramHashMap.put("text", DOCUMENTPATH)
            paramHashMap.put("mobile", DOCUMENTTO)

            //检查是否工单内发出的短信
            if (!KHUtil.isNull(Objective_Guid)) {
                paramHashMap.put("extend", Objective_Guid);
            }

            if (!KHUtil.isNull(SMS_CallbackURL)) {
                paramHashMap.put("callback_url", SMS_CallbackURL);

            }
            paramHashMap.put("uid", uid)

            String injson = SplicingMap(paramHashMap, "&")
            log.debug("待发送参数信息:" + injson)

            Map<String, String> headMap = new HashMap<String, String>()
            headMap.put("Content-Type", "application/x-www-form-urlencoded")
            Date date2 = new Date()
            String resTokenJson = Util.doHttpPostUseHead(KHDBConfig.getAPIURL(eliteBean, "YUNPIAN-SENDMSG"), injson, "UTF-8", 10000, 0, headMap)
            log.debug("resTokenJson: " + resTokenJson)
            JSONObject res = JSONObject.fromObject(resTokenJson)
            if (res.code == 0) {
                code = "0"
                msg = res.msg
            } else {
                code = "-1"
                msg = res.msg
            }
        } catch (Exception e) {
            log.error("接口处理异常", e)
            resultJson.put("errcode", -1)
            resultJson.put("errmsg", "接口处理异常" + e.getMessage())
            code = "-1"
        } finally {
            //短信发送结果更新
            if (code == "0") {
                // 发送成功
                eliteBean.update("Update Documentout Set Status = '1',uid = '" + uid + "', Trialcount = Trialcount + 1, Lasttrydatetime = Now(), Finishdatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            } else {
                // 发送失败
                eliteBean.update("Update Documentout Set uid = '" + uid + "' ,Status = Case When Trialcount + 1 >= Trialcountlimit Then '-1' Else Status End, Failcode = '" + code + " ', Faildescription =  '" + msg + "' , Trialcount = Trialcount + 1, Lasttrydatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            }
            log.debug("单条短信 耗时：" + System.currentTimeMillis() - startTime + "毫秒")
        }
    }

    // 发送企业微信（调用中间件提供的企业微信消息发送接口）
    static void sendWmsMessage(EliteBean eliteBean, String title, String url, String DOCUMENTOUT_GUID, String DOCUMENTTO, String DOCUMENTPATH, int num) {
        long startTime = System.currentTimeMillis()
        // 开始准备发送
        Map<String, Object> headMap = new HashMap<>()
        headMap.put("Content-Type", "application/json")

        String code = "-1" //短信发送状态
        String immediately = "yes"//是否即时发送，填yes即时发送
        String msgtype = "textcard"//消息类型，“textcard”为文本卡片类型

        //获取配置参数
        DGQW_KEY = KHUtil.isNull(DGQW_KEY) ? KHDBConfig.getParamConfig(eliteBean, "DGQW_KEY") : DGQW_KEY; //德高中间件接口-发送企业微信消息所需Key
        DGQW_AGENTID = KHUtil.isNull(DGQW_AGENTID) ? KHDBConfig.getParamConfig(eliteBean, "DGQW_AGENTID") : DGQW_AGENTID //德高中间件接口-发送企业微信消息所需企业号ID
        DGQW_SENDMSM = KHUtil.isNull(DGQW_SENDMSM) ? KHDBConfig.getAPIURL(eliteBean, "DGQW-SENDMSM") : DGQW_SENDMSM //德高中间件接口-发送企业微信URL

        SYS_OuterDomain = KHUtil.isNull(SYS_OuterDomain) ? KHDBConfig.getAPIURL(eliteBean, "SYS-OuterDomain") : SYS_OuterDomain //德高中间件接口-发送企业微信URL

        try {
            JSONObject requestJson = JSONObject.fromObject("{\"touser\":\"\",\"num\":\"0\",\"description\":\"\",\"immediately\":\"\",\"title\":\"\",\"msgtype\":\"\",\"url\":\"\",\"key\":\"\",\"agentid\":\"\"}");

            if (!KHUtil.isNull(DOCUMENTTO) && !KHUtil.isNull(title) && !KHUtil.isNull(DOCUMENTPATH)) {
                // 发送报文更新
                requestJson.put("key", DGQW_KEY);
                requestJson.put("agentid", DGQW_AGENTID);
                requestJson.put("touser", DOCUMENTTO);
                requestJson.put("immediately", immediately);
                requestJson.put("msgtype", msgtype);
                requestJson.put("title", title);
                requestJson.put("description", DOCUMENTPATH);
                requestJson.put("url", KHUtil.isNull(url) ? SYS_OuterDomain + "/ngs/no_support.html" : url);
                requestJson.put("num", num);
                log.debug("发送企业微信（调用中间件提供的企业微信消息发送接口） 接口内容：" + requestJson.toString());

                // 调用企微接口
                String responseInfo = Util.doHttpPostUseHead(DGQW_SENDMSM, requestJson.toString(), "utf-8", 60000, 1, headMap)
                log.debug("发送企业微信（调用中间件提供的企业微信消息发送接口） 发送结果：" + responseInfo);

                if (responseInfo == 'success') {
                    code = "0"
                } else {
                    code = "-1"
                }
            } else {
                log.warn("发送企业微信（调用中间件提供的企业微信消息发送接口） 处理警告:" + "关键信息为空");
            }

        } catch (Exception e) {
            log.error("发送企业微信（调用中间件提供的企业微信消息发送接口） 处理异常", Util.getERRO(e))
        } finally {
            if (code == "0") {
                // 发送成功
                eliteBean.update("Update Documentout Set Status = '1', Trialcount = Trialcount + 1, Lasttrydatetime = Now(), Finishdatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            } else {
                // 发送失败
                eliteBean.update("Update Documentout Set Status = Case When Trialcount + 1 >= Trialcountlimit Then '-1' Else Status End, Failcode = null , Faildescription = '发送失败', Trialcount = Trialcount + 1, Lasttrydatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            }
            log.debug("发送企业微信（调用中间件提供的企业微信消息发送接口） 耗时：" + System.currentTimeMillis() - startTime + " 毫秒" + DOCUMENTOUT_GUID)
        }
    }


    // 发送企业微信（调用原生企业微信接口发送）
    static void sendQwMessage(EliteBean eliteBean, String title, String url, String DOCUMENTOUT_GUID, String DOCUMENTTO, String DOCUMENTPATH) {
        long startTime = System.currentTimeMillis()
        // 开始准备发送
        Map<String, Object> headMap = new HashMap<>()
        headMap.put("Content-Type", "application/json")

        String code = "-1" //短信发送状态
        String msgtype = "textcard"//消息类型，“textcard”为文本卡片类型

        //获取配置参数
        QW_AgentID = KHUtil.isNull(QW_AgentID) ? KHDBConfig.getParamConfig(eliteBean, "QW_AgentID") : QW_AgentID //发送企业微信消息所需企业号ID

        try {
            JSONObject requestJson = JSONObject.fromObject("{\"touser\":\"\",\"toparty\":\"\",\"totag\":\"\",\"msgtype\":\"\",\"agentid\":0,\"textcard\":{\"title\":\"\",\"description\":\"\",\"url\":\"\",\"btntxt\":\"详情\"},\"enable_id_trans\":0,\"enable_duplicate_check\":0,\"duplicate_check_interval\":1800}\n");

            requestJson.put("touser", DOCUMENTTO);
            requestJson.put("toparty", "");
            requestJson.put("totag", "");
            requestJson.put("msgtype", msgtype);
            requestJson.put("agentid", QW_AgentID);
            requestJson.getJSONObject("textcard").put("title", title);
            requestJson.getJSONObject("textcard").put("description", DOCUMENTPATH);
            requestJson.getJSONObject("textcard").put("url", url);
            requestJson.put("enable_id_trans", 0);
            requestJson.put("enable_duplicate_check", 0);
            requestJson.put("duplicate_check_interval", 1800);
            log.debug("发送企业微信（调用原生企业微信接口发送） 接口内容：" + requestJson.toString());

            // 调用企微接口
            def responseInfo = Util.doHttpPostUseHead(KHDBConfig.getAPIURL(eliteBean, "SYS-InnerDomain") + "groovy/GeneralService/apiQWSendMSG", requestJson.toString(), "utf-8", 60000, 1, headMap)
            log.debug("发送企业微信（调用原生企业微信接口发送） 发送结果：" + responseInfo);

            JSONObject resultJson = JSONObject.fromObject(responseInfo)
            if (resultJson.errcode == 0) {
                code = "0"
            } else {
                code = "-1"
            }

        } catch (Exception e) {
            log.error("发送企业微信（调用原生企业微信接口发送） 处理异常", Util.getERRO(e))
        } finally {
            if (code == "0") {
                // 发送成功
                eliteBean.update("Update Documentout Set Status = '1', Trialcount = Trialcount + 1, Lasttrydatetime = Now(), Finishdatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            } else {
                // 发送失败
                eliteBean.update("Update Documentout Set Status = Case When Trialcount + 1 >= Trialcountlimit Then '-1' Else Status End, Failcode = null , Faildescription = '发送失败', Trialcount = Trialcount + 1, Lasttrydatetime = Now() Where Documentout_Guid = '" + DOCUMENTOUT_GUID + "'", "dataSource")
            }
            log.debug("发送企业微信（调用原生企业微信接口发送） 耗时：" + System.currentTimeMillis() - startTime + "毫秒" + DOCUMENTOUT_GUID)
        }
    }

    // 参数处理
    static String SplicingMap(Map<String, String> param, String Splicing) {
        TreeMap<String, String> paramTreeMap = new TreeMap<>(param)
        String prestr = ""
        for (Map.Entry<String, String> vo : paramTreeMap.entrySet()) {
            vo.getKey()
            vo.getValue()
            prestr = prestr + Splicing + vo.getKey() + "=" + vo.getValue()
        }
        prestr = prestr.substring(1)
        return prestr
    }
}